﻿namespace Manhua2.Helper
{
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Text.RegularExpressions;

    public static class JavaScriptHelper
    {
        private static char[] chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".ToCharArray();

        private static string To36(this int value, int toBase)
        {
            if (value == 0) return "0";

            int digitIndex = 0;
            long longPositive = Math.Abs(value);
            int radix = toBase;
            char[] outDigits = new char[63];

            for (digitIndex = 0; digitIndex <= 64; digitIndex++)
            {
                if (longPositive == 0) { break; }

                outDigits[outDigits.Length - digitIndex - 1] =
                     chars[longPositive % radix];
                longPositive /= radix;
            }

            return new string(outDigits, outDigits.Length - digitIndex, digitIndex);
        }

        public static string Decode(string script)
        {
            var match = Regex.Match(script, @"eval\(.*\)");
            if (!match.Success)
            {
                throw new ArgumentException("漫画加载失败");
            }

            string input = match.Value;
            input = input.Substring(input.IndexOf('(') + 1);
            input = input.Remove(input.Length - 1, 1);
            
            string[] array = SearchParam(input);
            input = array[array.Length - 1];

            string[] args = ParamSplit(input);

            int c = int.Parse(args[2]);
            int a = int.Parse(args[1]);
            string p = args[0];
            Dictionary<string, string> d = new Dictionary<string, string>();
            string[] k = args[3].Remove(args[3].LastIndexOf('.')).Trim('\'').Split('|');

            while (c-- > 0)
            {
                d[c.To36(a)] = string.IsNullOrEmpty(k[c]) ? c.To36(a) : k[c];
            }

            p = Regex.Replace(
                p,
                "\\b\\w+\\b",
                m =>
                {
                    return d[m.Value];
                });

            return p;

            //string[] strArray = ParamSplit(regex.Match(script).Groups[1].Value, ",".ToCharArray());
            //string input = strArray[0];
            //int c = Convert.ToInt32(strArray[2]);
            //string str3 = strArray[3];
            //string[] strArray2 = Regex.Match(str3, @"'(.*)'\.split.*").Groups[1].Value.Split("|".ToCharArray());
            //Dictionary<string, string> d = new Dictionary<string, string>();
            //while (--c >= 0)
            //{
            //    string str4 = To36(c);
            //    if ((c < strArray2.Length) && !string.IsNullOrEmpty(strArray2[c]))
            //    {
            //        d[str4] = strArray2[c];
            //    }
            //    else
            //    {
            //        d[str4] = str4;
            //    }
            //}
            //regex = new Regex(@"\b\w+\b");
            //return regex.Replace(input, m => d[m.Value]).Trim(new char[] { '\'' }).Replace(@"\'", "'");
        }

        public static string[] SearchParam(string str)
        {
            StringBuilder sb = new StringBuilder();
            sb.Append(str);
            
            List<string> list = new List<string>();
            Stack<char> stack = new Stack<char>();

            for (int i = 0; i < sb.Length; i++)
            {
                if (sb[i] == '(')
                {
                    stack.Push('(');

                    StringBuilder tmp = new StringBuilder('(');
                    while (i < sb.Length)
                    {
                        i++;

                        if (sb[i] == '(')
                        {
                            stack.Push('(');
                        }

                        if (sb[i] == ')')
                        {
                            if (stack.Pop() != '(')
                                throw new ArgumentException();

                            sb.Append(')');
                            if (stack.Count == 0)
                                break;
                        }

                        tmp.Append(sb[i]);
                    }

                    if (stack.Count != 0)
                        throw new ArgumentException();

                    list.Add(tmp.ToString());
                    tmp.Clear();
                }
            }

            return list.ToArray();
        }

        public static string[] ParamSplit(string str)
        {
            StringBuilder sb = new StringBuilder();
            sb.Append(str);

            List<string> list = new List<string>();

            for (int i = 0; i < sb.Length; i++)
            {
                StringBuilder tmp = new StringBuilder();

                if (sb[i] == '\'')
                {
                    do
                    {
                        tmp.Append(sb[i]);
                        i++;

                        if (sb[i] == '\'' && sb[i - 1] != '\\')
                        {
                            break;
                        }
                    }
                    while (i < sb.Length);
                }

                while (i < sb.Length && sb[i] != ',')
                {
                    tmp.Append(sb[i]);
                    i++;
                }

                list.Add(tmp.ToString());
                tmp.Clear();
            }

            return list.ToArray();
        }
    }
}
